package com.ceair.flight.refund.service.cronjob.impl;

import com.ceair.flight.refund.dto.BaseAuditReq;
import com.ceair.flight.refund.dto.appmoblie.RefundApplyDto;
import com.ceair.flight.refund.dto.appmoblie.RefundAuditDto;
import com.ceair.flight.refund.location.dao.IRefundApplyDao;
import com.ceair.flight.refund.location.dt.enums.AuditPhase;
import com.ceair.flight.refund.location.dt.enums.AuditStatus;
import com.ceair.flight.refund.location.dt.enums.RefundAutoAuditEnum;
import com.ceair.flight.refund.location.dt.enums.RefundStatusEnum;
import com.ceair.flight.refund.service.cronjob.ISecondAuditService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;

@Service
public class SecondAuditServiceImpl implements ISecondAuditService {

    private static final Logger LOG = LoggerFactory.getLogger(SecondAuditServiceImpl.class);
    @Autowired
    private IRefundApplyDao applyDao;

    /**
     * 二审通过
     *
     * @param auditReq
     * @param auto 是否是自动
     * @return
     */
    @Override
    public RefundApplyDto doAuditPass(BaseAuditReq auditReq, boolean auto) {
        long applyId = auditReq.getApplyId();
        RefundApplyDto refundApply = loadAndCheck(applyId);

        LOG.info("Refund apply {} pass the second audit", applyId);
        LOG.info("Change refund apply {} status to {}", applyId, RefundStatusEnum.SECOND_AUDIT_PASS.name());
        refundApply.setStatus(RefundStatusEnum.SECOND_AUDIT_PASS.getCode());
        refundApply.setUpdatDate(new Date());
        applyDao.updateRefundApply(refundApply);
        if (auto) {
            refundApply.setAutoSecondAudit(RefundAutoAuditEnum.PASS.getCode());
        }
        saveAudit(auditReq, refundApply, AuditStatus.PASS);
        return refundApply;
    }

    /**
     * 二审拒绝
     *
     * @param auditReq
     * @return
     */
    @Override
    public RefundApplyDto doAuditRefuse(BaseAuditReq auditReq) {
        long applyId = auditReq.getApplyId();
        RefundApplyDto refundApply = loadAndCheck(applyId);

        LOG.info("Refund apply {} is refused on second audit", auditReq.getApplyId());
        refundApply.setStatus(RefundStatusEnum.SECOND_AUDIT_REFUSE.getCode());
        refundApply.setUpdatDate(new Date());
        LOG.info("Change refund apply '{}' status to {}", applyId, RefundStatusEnum.SECOND_AUDIT_REFUSE.name());
//        applyDao.updateRefundApply(refundApply);

        saveAudit(auditReq, refundApply, AuditStatus.REFUNSE);
        return refundApply;
    }

    private void saveAudit(BaseAuditReq auditReq, RefundApplyDto refundApply, AuditStatus status) {
        RefundAuditDto audit = buildRefundAudit(auditReq);
        int auditStatus = status.getCode();
        audit.setAuditStatus(auditStatus);
        audit.setRefundApply(refundApply);
        //mybatis写法
        applyDao.insertRefundAudit(audit);
//        refundApply.addRefundAudit(audit);
    }

    private RefundApplyDto loadAndCheck(long applyId) {
        RefundApplyDto refundApply = loadRefundApply(applyId);
        if (!checkRefundApplyStatus(refundApply)) {
            LOG.warn("Refund apply '{}' status '{}' is not valid for second audit", refundApply.getId(), refundApply.getStatus());
            throw new IllegalStateException("The status of refund apply " + applyId + " is not valid for second audit");
        }
        return refundApply;
    }

    /**
     * 检查申请单是否符合二审条件, 目前仅检查申请单状态是否是等待二审
     */
    private boolean checkRefundApplyStatus(RefundApplyDto entity) {
        String status = entity.getStatus();
        LOG.info("Checking refund apply status {}", status);
        RefundStatusEnum refundStatus = RefundStatusEnum.getByCode(status);
        return refundStatus != null && refundStatus == RefundStatusEnum.WAIT_SECOND_AUDIT;
    }

    private RefundApplyDto loadRefundApply(long applyId) {
        return applyDao.getRefundApplyDto(applyId);
    }

    private RefundAuditDto buildRefundAudit(BaseAuditReq auditReq) {
        RefundAuditDto audit = new RefundAuditDto();
        audit.setAuditorId(auditReq.getSessionUserId());
        audit.setAuditorName(auditReq.getAuditName());
        audit.setAuditDate(new Date());
        audit.setAuditDesc(auditReq.getRemark());
        audit.setAuditPhase(String.valueOf(AuditPhase.SECOND_AUDIT.getCode()));
        return audit;
    }

}
